package com.oanda.blackberry.net;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;

import javax.microedition.io.ConnectionNotFoundException;
import javax.microedition.io.HttpConnection;

import com.oanda.blackberry.util.log.Logger;

public class UpgradeCheck {
    boolean error;
    String errorMessage;
    String response;

    public String proceedConnection(String url) {
        HttpConnection connection = null;
        InputStream inputstream = null;
        OutputStream outputstream = null;

        int responseCode = 0;
        String responseMessage = "";

        this.error = false;
        this.errorMessage = "";
        this.response = "";
        try {
            Logger.log(url);
            Logger.log("connecting");
            connection = AutoConnectionManager.requestNonSecure(url);

            if (connection == null) {
                this.error = true;
                this.errorMessage = "Unable to open connection.";
            } else {
                Logger.log("opened");

                connection.setRequestMethod("GET");
                connection.setRequestProperty("User-Agent",
                        "Profile/MIDP-2.0 Configuration/CLDC-1.0");
                connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                connection.setRequestProperty("Connection", "Keep-Alive");

                Logger.log("set requested properties and waiting reponse code");

                responseCode = connection.getResponseCode();
                responseMessage = connection.getResponseMessage();
                Logger.log(String.valueOf(responseCode) + responseMessage);

                Logger.log("waiting input stream...");
                inputstream = connection.openInputStream();

                if ((responseCode == 200) || (isError(responseCode))) {
                    int length = (int) connection.getLength();
                    if (length != -1) {
                        byte[] incomingData = new byte[length];
                        inputstream.read(incomingData);
                        String receivedText = new String(incomingData);
                        this.response = receivedText;
                    } else {
                        ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
                        int ch;
                        while ((ch = inputstream.read()) != -1) {
                            bytestream.write(ch);
                        }
                        String receivedText = new String(bytestream.toByteArray());
                        bytestream.close();

                        this.response = bytestream.toString();
                    }

                } else {
                    Logger.log(String.valueOf(responseCode) + ":" + responseMessage);
                    this.error = true;
                    this.errorMessage = (String.valueOf(responseCode) + ": " + responseMessage);
                }

            }

        } catch (InterruptedIOException io) {
            this.error = true;
            this.errorMessage += "InterruptedIOException: ";
            this.errorMessage += io.getMessage();
            Logger.log("InterruptedIOException: " + io.getMessage());
        } catch (ConnectionNotFoundException cn) {
            this.error = true;
            this.errorMessage += "ConnectionNotFoundException: ";
            this.errorMessage += cn.getMessage();
            Logger.log("ConnectionNotFoundException: " + cn.getMessage());
        } catch (IOException io) {
            this.error = true;
            this.errorMessage += "IOException: ";
            this.errorMessage += io.getMessage();
            Logger.log("IOException: " + io.getMessage());
        } catch (Exception e) {
            this.error = true;
            this.errorMessage += "Exception: ";
            this.errorMessage += e.getMessage();
            Logger.log("Exception: " + e.getMessage());
        } catch (Throwable t) {
            this.error = true;
            this.errorMessage += "Throwable: ";
            this.errorMessage += t.getMessage();
            Logger.log("Throable(Serious rest exception) : " + t.getMessage());
        } finally {
            try {
                if (inputstream != null) {
                    inputstream.close();
                    Logger.log("inpustream closed");
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
                Logger.log("error in closing input stream");
            }
            try {
                if (outputstream != null) {
                    outputstream.close();
                    Logger.log("outputstream closed");
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
                Logger.log("login.json: error in closing output stream");
            }

            try {
                if (connection != null) {
                    connection.close();
                    Logger.log("connections closed");
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
                Logger.log("login.json: error in closing connections");
            }
        }

        if (this.error) {
            Logger.log("response code: " + String.valueOf(responseCode) + " response message: "
                    + (responseMessage == null ? "" : responseMessage) + " error message: "
                    + this.errorMessage + (this.response == null ? "" : this.response));

            return "";
        }

        Logger.log("" + this.response);
        return this.response;
    }

    boolean isError(int responseCode) {
        if ((responseCode == 400) || (responseCode == 403) || (responseCode == 500)
                || (responseCode == 404)) {
            this.error = true;
            return true;
        }

        return false;
    }
}
